<?php

namespace App\Common\Librarys\aws;

use Aws\S3\S3Client;
use Hyperf\Logger\Logger;

/**
 * s3协议 支持阿里云oss，亚马逊AWS，MINIO等
 */
class FileStorageUtil
{
    /**
     * @param string $bucket
     * @return S3Client
     */
    private static function getClient($bucket): S3Client
    {
        $s3Config = config('s3.' . $bucket);
        return new S3Client([
            'version' => $s3Config['version'],
            'endpoint' => $s3Config['endpoint'],
            'region' => $s3Config['region'],
            'use_path_style_endpoint' => $s3Config['use_path_style_endpoint'],
            'credentials' => [
                'key' => $s3Config['credentials']['key'],
                'secret' => $s3Config['credentials']['secret']
            ]
        ]);
    }

    /**
     * 上传文件到存储系统  返回存储链接
     * @param string $bucket
     * @param string $key
     * @param string $filePath
     * @return string
     */
    public static function uploadFile(string $bucket, string $key, string $filePath): string
    {
        try {
            $s3Client = self::getClient($bucket);
            $s3_return = $s3Client->putObject([
                'Bucket' => $bucket, //存储桶名称
                'Key' => $key, //文件名（包括后缀名）
                'SourceFile' => $filePath
            ]);
            Logger::info('S3 upload file result', [
                'result' => $s3_return
            ]);
            if ($s3_return['@metadata']['statusCode'] != 200) {
                Logger::error("Upload file fail", $s3_return['@metadata']);
                return '';
            }
            return $s3_return['ObjectURL'];
        } catch (\Exception $exception) {
            Logger::error("Upload file fail : " . $exception->getMessage());
        }
    }

    /**
     * 获取签名地址
     * @param string $bucket
     * @param string $key
     * @param int $minutes
     * @return string
     */
    public static function getSigned(string $bucket, string $key, int $minutes = 20): string
    {
        try {
            $s3 = self::getClient($bucket);
            $cmd = $s3->getCommand('GetObject', [
                'Bucket' => $bucket,
                'Key' => $key
            ]);
            return $s3->createPresignedRequest($cmd, '+' . $minutes . ' minutes')->getUri() ?? '';
        } catch (\Exception $exception) {
            Logger::info('签名失败', [
                'bucket' => $bucket,
                'key' => $key,
                'message' => $exception->getMessage()
            ]);
            return '';
        }
    }
}